package com.cqupt.scanning.system.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.scanning.handler.exception.MyException;
import com.cqupt.scanning.system.acl.entity.AclUserRole;
import com.cqupt.scanning.system.acl.service.AclUserService;
import com.cqupt.scanning.system.admin.entity.Department;
import com.cqupt.scanning.system.admin.entity.DeviceFoot;
import com.cqupt.scanning.system.admin.entity.DeviceThree;
import com.cqupt.scanning.system.admin.entity.Organization;
import com.cqupt.scanning.system.admin.entity.dto.DepartmentDTO;
import com.cqupt.scanning.system.admin.entity.dto.DeviceDTO;
import com.cqupt.scanning.system.admin.entity.dto.OrganizationDTO;
import com.cqupt.scanning.system.admin.mapper.OrganizationMapper;
import com.cqupt.scanning.system.admin.service.DepartmentService;
import com.cqupt.scanning.system.admin.service.DeviceFootService;
import com.cqupt.scanning.system.admin.service.DeviceThreeService;
import com.cqupt.scanning.system.admin.service.OrganizationService;
import com.cqupt.scanning.system.utils.result.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 宋宝梁
 * @since 2021-07-06
 */
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements OrganizationService {


    @Lazy
    @Autowired
    private DeviceFootService deviceFootService;
    @Autowired
    private DepartmentService departmentService;
    @Lazy
    @Autowired
    private DeviceThreeService deviceThreeService;
    @Autowired
    private AclUserService aclUserService;



    @Override
    public R insert(Organization organization) {
        String orgNum = organization.getOrgNum();
        if (orgNum == null || StrUtil.hasBlank(orgNum)) return R.error().message("机构编码不能为空");

        Integer count = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_num", orgNum));
        if (count > 0) return R.error().message("机构编码已经存在");

        baseMapper.insert(organization);
        return R.ok().data("orgId", organization.getId());
    }

    @Override
    public R getAll(Page<Organization> page, String query) {
        IPage<Organization> organizationIPage = baseMapper.selectPage(page,
                new QueryWrapper<Organization>()
                        .isNotNull("org_num")
                        .like("org_name", query));
        return R.ok().data("orgs", organizationIPage);
    }

    @Override
    public R getDepAndDevById(Integer id) {
        Organization organizationFoot = baseMapper.getDepAndDevFootById(id);
        Organization organizationThree = baseMapper.getDepAndDevThreeById(id);
        OrganizationDTO orgDTO = new OrganizationDTO();
        BeanUtils.copyProperties(organizationFoot, orgDTO);
        List<DepartmentDTO> departments = orgDTO.getDepartments();
        List<DepartmentDTO> departments_three = organizationThree.getDepartments();
        for (DepartmentDTO departmentDTO : departments_three) {
            for (DepartmentDTO department : departments) {
                if (departmentDTO.getId().equals(department.getId())) {
                    List<DeviceDTO> devices = department.getDevices();
                    List<DeviceDTO> _devices = departmentDTO.getDevices();
                    devices.addAll(_devices);
                }
            }
        }
        return R.ok().data("organization", orgDTO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public R removeById(Integer orgId) {
        try {
            Organization organization = baseMapper.selectOne(new QueryWrapper<Organization>().eq("id",orgId).select("org_num"));
            Department department = departmentService.getOne(new QueryWrapper<Department>().eq("org_num",organization.getOrgNum()));
            if(department == null)
            {
                baseMapper.deleteById(orgId);
            }
            else {
                List<Department> departmentList = departmentService.list(new QueryWrapper<Department>().eq("org_num", organization.getOrgNum()));
                List<Integer> departmentIds = departmentList.stream().map(Department::getId).collect(Collectors.toList());

                DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().eq("dep_id", department.getId()));
                DeviceThree deviceThree = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().eq("dep_id",department.getId()));

                List<DeviceFoot> deviceFootList = deviceFootService.list(new QueryWrapper<DeviceFoot>().eq("dep_id", department.getId()));
                List<Integer> footIds = deviceFootList.stream().map(DeviceFoot::getId).collect(Collectors.toList());
                List<Integer> userFootIds = deviceFootList.stream().map(DeviceFoot::getUserId).collect(Collectors.toList());

                List<DeviceThree> deviceThreeList = deviceThreeService.list(new QueryWrapper<DeviceThree>().eq("dep_id", department.getId()));
                List<Integer> threeIds = deviceThreeList.stream().map(DeviceThree::getId).collect(Collectors.toList());
                List<Integer> userThreeIds = deviceThreeList.stream().map(DeviceThree::getUserId).collect(Collectors.toList());

                if (deviceFoot == null||deviceThree == null) {
                    if(deviceFoot== null&&deviceThree == null)
                    {
                        departmentService.removeByIds(departmentIds);
                        baseMapper.deleteById(orgId);
                    }
                    else if(deviceFoot == null)
                    {
                        deviceThreeService.removeByIds(threeIds);
                        aclUserService.removeByIds(userThreeIds);
                        departmentService.removeByIds(departmentIds);
                        baseMapper.deleteById(orgId);
                    }else{
                        deviceFootService.removeByIds(footIds);
                        aclUserService.removeByIds(userFootIds);
                        departmentService.removeByIds(departmentIds);
                        baseMapper.deleteById(orgId);
                    }
                } else {
 //                   deviceThreeService.removeById(deviceThree.getId());//删除单个三维设备
                    deviceThreeService.removeByIds(threeIds);
                    aclUserService.removeByIds(userThreeIds);
 //                   deviceFootService.removeById(deviceFoot.getId());//删除单个足底设备
                    deviceFootService.removeByIds(footIds);
                    aclUserService.removeByIds(userFootIds);
 //                   departmentService.removeById(department.getId()); //删除单个科室
                    departmentService.removeByIds(departmentIds);
                    baseMapper.deleteById(orgId);
                }

            }
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException(20001, "Remove failed");
        }
    }
    @Override
    public R update(Map<String,Object> dataMap){
        dataMap.remove("departments");
        Organization organization= JSON.parseObject(JSON.toJSONString(dataMap),Organization.class);
        Integer count = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_Name",organization.getOrgName()).ne("id",organization.getId()));
        if (count >= 1) return R.error().message("该医院重名");
        Integer countTwo = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_Num",organization.getOrgNum()).ne("id",organization.getId()));
        if (countTwo >= 1) return R.error().message("该医院编号重名");
        int id = baseMapper.updateById(organization);
        if (id <= 0) R.error().message("添加失败，请重新操作");
        return R.ok();
    }
}
